home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
Other Langs
/
MacPerl ƒ
/
Perl Source ƒ
/
MacPerl
/
MPSave.c
< prev
next >
Wrap
Text File
|
1994-01-15
|
9KB
|
420 lines
/*********************************************************************
Project : MacPerl - Real Perl Application
File : MPSave.c - Handle all the runtimes
Author : Matthias Neeracher
A lot of this code is borrowed from 7Edit written by
Apple Developer Support UK
Started : 03Oct93 Language : MPW C
Modified : 03Oct93 MN Compiles correctly
Last : 03Oct93
*********************************************************************/
#include <Errors.h>
#include <Resources.h>
#include <PLStringFuncs.h>
#include <SysEqu.h>
#include <Folders.h>
#include "MPSave.h"
#include "MPGlobals.h"
#include "MPFile.h"
#include "MPUtils.h"
#pragma segment File
OSErr DoOpenResFile(FSSpec * spec, short * resFile, Boolean bundle)
{
OSErr err;
*resFile = HOpenResFile(spec->vRefNum, spec->parID, spec->name, fsRdWrPerm);
if (*resFile == -1) {
if (err = DoCreate(*spec))
return err;
*resFile = HOpenResFile(spec->vRefNum, spec->parID, spec->name, fsRdWrPerm);
if (*resFile == -1) {
FileError("\perror opening file ", spec->name);
return ResError();
}
}
if (bundle) {
FInfo info;
HGetFInfo(spec->vRefNum, spec->parID, spec->name, &info);
info.fdType = 'APPL';
info.fdCreator = MPRtSig;
info.fdFlags |= fHasBundle;
HSetFInfo(spec->vRefNum, spec->parID, spec->name, &info);
}
return noErr;
}
typedef struct {
OSType type;
short id;
OSType realType;
} ShoppingList;
OSErr CopyShoppingList(short from, short to, ShoppingList * list)
{
OSErr err;
while (list->type) {
Handle rsrc;
Handle nur;
UseResFile(from);
rsrc = Get1Resource(list->type, list->id);
if (!rsrc)
return ResError();
UseResFile(to);
if (nur = Get1Resource(list->realType, list->id))
RmveResource(nur);
DetachResource(rsrc);
AddResource(rsrc, list->realType, list->id, "\p");
if (err = ResError())
goto finish;
++list;
}
finish:
UseResFile(from);
return err;
}
OSErr CopyRsrc(FSSpec * from, FSSpec * to)
{
OSErr err;
short res;
short fromRef;
short toRef;
Handle copy;
Ptr buffer;
long len;
copy = NewHandle(4096);
buffer = *copy;
HLock(copy);
if (err = DoOpenResFile(to, &res, true))
goto disposeBuffer;
CloseResFile(res);
if (err = HOpenRF(from->vRefNum, from->parID, from->name, fsRdPerm, &fromRef))
goto disposeBuffer;
if (err = HOpenRF(to->vRefNum, to->parID, to->name, fsRdWrPerm, &toRef))
goto closeFrom;
do {
len = 4096;
FSRead(fromRef, &len, buffer);
FSWrite(toRef, &len, buffer);
} while (len == 4096);
FSClose(toRef);
closeFrom:
FSClose(fromRef);
disposeBuffer:
DisposeHandle(copy);
return err;
}
ShoppingList DropletShopping[] =
{
{ 'MrPC', 0, 'CODE' },
{ 'MrPC', 1, 'CODE' },
{ 'MrPC', 2, 'CODE' },
{ 'MrPB', 128, 'BNDL' },
{ 'MrPL', 0, 'MrPL' },
{ 'MrPS', -1, 'SIZE' },
{ 'MrPI', 128, 'ICN#' },
{ 'MrP4', 128, 'icl4' },
{ 'MrP8', 128, 'icl8' },
{ 'MrP#', 128, 'ics#' },
{ 'MrPA', 4096, 'ALRT' },
{ 'MrPD', 4096, 'DITL' },
{ 'FREF', 128, 'FREF' },
{ 'FREF', 129, 'FREF' },
{ 'FREF', 131, 'FREF' },
{ 'MrPF', 132, 'FREF' },
{ 'MrPF', 133, 'FREF' },
{ 'MrPF', 134, 'FREF' },
{ 0, 0, 0 }
};
OSErr MakeDroplet(FSSpec * spec, short * resFile)
{
OSErr err;
if (err = DoOpenResFile(spec, resFile, true))
return err;
return CopyShoppingList(gAppFile, *resFile, DropletShopping);
}
OSErr Make6Runtime(FSSpec * spec, short * resFile)
{
OSErr err;
FSSpec from;
from.vRefNum = gAppVol;
from.parID = gAppDir;
PLstrcpy(from.name, "\pMacPerl Runtime");
if (!CopyRsrc(&from, spec))
return DoOpenResFile(spec, resFile, false);
err =
FindFolder(
kOnSystemDisk,
kPreferencesFolderType,
true,
&from.vRefNum,
&from.parID);
if (err || (err = CopyRsrc(&from, spec))) {
DialogPtr dlg;
short item;
ParamText(
"\pTo create System 6 compatible Perl runtimes, I need"
"\"MacPerl Runtime\" in the same folder as this application or"
"in the preferences folder.", "\pOK", "\p", "\p");
dlg = GetNewDialog(2001, (WindowPtr) nil, (WindowPtr) -1);
ShowWindow(dlg);
ModalDialog(nil, &item);
DisposeDialog(dlg);
return userCanceledErr;
}
return DoOpenResFile(spec, resFile, false);
}
ShoppingList Runtime7Shopping[] =
{
{ 'MrPB', 128, 'BNDL' },
{ 'MrPI', 128, 'ICN#' },
{ 'MrP4', 128, 'icl4' },
{ 'MrP8', 128, 'icl8' },
{ 'MrP#', 128, 'ics#' },
{ 'MrPF', 132, 'FREF' },
{ 'MrPF', 133, 'FREF' },
{ 'MrPF', 134, 'FREF' },
{ 0, 0, 0 }
};
OSErr Make7Runtime(FSSpec * spec, short * resFile)
{
OSErr err;
FSSpec from;
from.vRefNum = gAppVol;
from.parID = gAppDir;
PLstrcpy(from.name, (StringPtr) CurApName);
if (err = CopyRsrc(&from, spec))
return err;
if (err = DoOpenResFile(spec, resFile, false))
return err;
return CopyShoppingList(gAppFile, *resFile, Runtime7Shopping);
}
#ifdef RUNTIME
#define HOpenDF HOpen
#endif
pascal OSErr DoSave(DPtr theDocument, FSSpec theFSSpec)
{
OSErr err;
short resFile;
OSType type;
Handle text = (*(theDocument->theText))->hText;
Handle thePHandle;
HHandle theHHandle;
StringHandle theAppName;
HDelete(theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name);
switch (theDocument->type) {
case kPlainTextDoc:
{
short refNum;
long length;
if (err = DoOpenResFile(&theFSSpec, &resFile, false))
return err;
if (err =
HOpenDF(
theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name,
fsRdWrPerm, &refNum)
) {
if (err = DoCreate(theFSSpec))
goto closeResource;
if (err =
HOpenDF(
theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name,
fsRdWrPerm, &refNum)
) {
FileError("\perror opening file ", theFSSpec.name);
goto closeResource;
}
}
length = GetHandleSize(text);
HLock(text);
err = FSWrite(refNum, &length, *text);
HUnlock(text);
FSClose(refNum);
if (err)
goto closeResource;
}
break;
case kScriptDoc:
if (err = MakeDroplet(&theFSSpec, &resFile))
return err;
type = 'SCPT';
goto writeScript;
case kRuntime6Doc:
if (err = Make6Runtime(&theFSSpec, &resFile))
return err;
type = 'MrP6';
goto writeScript;
case kRuntime7Doc:
if (err = Make7Runtime(&theFSSpec, &resFile))
return err;
type = 'MrP7';
writeScript:
if (err = HandToHand(&text))
goto closeResource;
UseResFile(resFile);
AddResource(text, 'TEXT', 128, "\p!");
if (err = ResError()) {
DisposeHandle(text);
goto closeResource;
}
if (err = PtrToHand(&type, &text, 4))
goto closeResource;
AddResource(text, 'MrPL', 128, "\p");
if (err = ResError()) {
DisposeHandle(text);
goto closeResource;
}
break;
}
/* write out the printer info */
if (theDocument->thePrintSetup) {
thePHandle = (Handle)theDocument->thePrintSetup;
HandToHand(&thePHandle);
AddResource(thePHandle, 'TFSP', 255, "\pPrinter Info");
err = ResError();
if (err = ResError()) {
ShowError("\pAddResource TFSP", err);
return err;
}
}
theHHandle = (HHandle)NewHandle(sizeof(HeaderRec));
HLock((Handle)theHHandle);
(*theHHandle)->theRect = theDocument->theWindow->portRect;
OffsetRect(
&(*theHHandle)->theRect,
-theDocument->theWindow->portBits.bounds.left,
-theDocument->theWindow->portBits.bounds.top);
GetFontName((*(theDocument->theText))->txFont, &(*theHHandle)->theFont);
(*theHHandle)->theSize = (*(theDocument->theText))->txSize;
(*theHHandle)->lastID = theDocument->kind == kDocumentWindow ? theDocument->u.reg.lastID : 0;
(*theHHandle)->numSections = theDocument->kind == kDocumentWindow ? theDocument->u.reg.numSections : 0;
HUnlock((Handle)theHHandle);
AddResource((Handle)theHHandle, 'TFSS', 255, "\pHeader Info");
if (err = ResError()) {
ShowError("\pAddResource- TFSS", err);
return err;
}
#ifndef RUNTIME
/*if we have any sections, write out the records and resources*/
if (theDocument->kind == kDocumentWindow && theDocument->u.reg.numSections) {
/*now write out the section records*/
SaveSections(theDocument);
/*write the latest versions of all editions to their containers*/
WriteAllEditions(theDocument);
}
#endif
if (theDocument->type == kPlainTextDoc) {
/*Now put an AppName in for Finder in 7.0*/
theAppName = (StringHandle)NewHandle(8);
PLstrcpy(*theAppName,"\pMacPerl");
AddResource((Handle)theAppName, 'STR ', - 16396, "\pFinder App Info");
if (err = ResError()) {
ShowError("\pAppName", err);
return err;
}
}
if (theDocument->kind == kDocumentWindow) {
theDocument->dirty = false;
theDocument->u.reg.everSaved = true;
}
closeResource:
CloseResFile(resFile);
UseResFile(gAppFile);
return err;
}